package com.lyon.demo.protocol.netty.command;

import cn.hutool.core.util.SerializeUtil;
import com.lyon.demo.protocol.api.core.command.RemotingCommandType;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * @author YLI1
 */
@SuppressWarnings({"rawtypes", "unchecked"})
@Data
@EqualsAndHashCode(callSuper = true)
public class CommonRemoteCommand<T> extends RemoteCommand<T> {

    public CommonRemoteCommand(byte commandType, int handlerCode, byte[] payload) {
        this.header = new CommonHeader(handlerCode, commandType);
        this.payload = payload;
    }

    @Override
    public int length() {
        return 0;
    }

    /**
     * @see com.lyon.demo.protocol.api.core.RemoteHandlerCodes of handlerCode
     * @param handlerCode  处理类型
     * @param payload 数据
     * @param <T> 数据泛型
     * @return 命令
     */
    public static <T> RemoteCommand<T> ofRequest(int handlerCode, byte[] payload) {
        return new CommonRemoteCommand<>(RemotingCommandType.REQUEST, handlerCode, payload);
    }

    @SuppressWarnings("unused")
    public static <T> RemoteCommand<T> ofRequest(int handlerCode, T data) {
        byte[] payload = null;
        if (data != null) {
            payload = SerializeUtil.serialize(data);
        }
        return new CommonRemoteCommand<>(RemotingCommandType.REQUEST, handlerCode, payload);
    }

    @SuppressWarnings("unused")
    public static <T> RemoteCommand<T> ofResponse(RemoteCommand source) {
        return ofResponse(source, null);
    }

    public static <T> RemoteCommand<T> ofResponse(RemoteCommand source, T data) {
        RemoteCommand<T> remoteCommand = SerializeUtil.clone(source);
        remoteCommand.setCommandType(RemotingCommandType.RESPONSE);
        if (data != null) {
            remoteCommand.setPayload(SerializeUtil.serialize(data));
        }
        return remoteCommand;
    }

}